import * as THREE from 'three'
import { gui } from '../gui'
import { stats } from '../stats'

function createCourse09 (dom: HTMLElement) {
  const scene = new THREE.Scene()
  const camera = new THREE.PerspectiveCamera(75, dom.offsetWidth / dom.offsetHeight, 0.1, 1000)

  const render = new THREE.WebGLRenderer()
  render.setClearColor(new THREE.Color(0x000000))
  render.setSize(dom.offsetWidth, dom.offsetHeight)
  render.shadowMap.enabled = true

  dom.appendChild(render.domElement)

  // show axes in the screen
  const axes = new THREE.AxesHelper(50)
  scene.add(axes)

  const planeGeometry = new THREE.PlaneGeometry(100, 100)
  const planeMaterial = new THREE.MeshLambertMaterial({ color: 0xAAAAAA })
  const plane = new THREE.Mesh(planeGeometry, planeMaterial)

  plane.rotation.x = -0.5 * Math.PI
  plane.position.set(15, 0, 0)
  plane.receiveShadow = true

  scene.add(plane)

  camera.position.x = -30
  camera.position.y = 140
  camera.position.z = 30
  camera.lookAt(scene.position)

  const spotLight = new THREE.SpotLight(0xFFFFFF)
  spotLight.position.set(-60, 30, -65)
  spotLight.castShadow = true
  spotLight.shadow.mapSize = new THREE.Vector2(1024, 1024)
  spotLight.shadow.camera.far = 130
  spotLight.shadow.camera.near = 40

  scene.add(camera)
  // If you want a more detailled shadow you can increase the
  // mapSize used to draw the shadows.
  // spotLight.shadow.mapSize = new THREE.Vector2(1024, 1024);
  scene.add(spotLight)

  const lightHelper = new THREE.SpotLightHelper(spotLight)
  scene.add(lightHelper)

  const shadowCameraHelper = new THREE.CameraHelper(spotLight.shadow.camera)
  scene.add(shadowCameraHelper)

  const ambienLight = new THREE.AmbientLight(0xcccccc)
  // scene.add(ambienLight);

  const ctrlObj = {
    // AmbientLight
    ambienLightintensity: 1,
    ambienLightColor: 0xcccccc,
    // SpotLight
    spotLightintensity: 1,
    spotLightColor: 0xFFFFFF,
    spotLightDistance: 0,
    spotLightAngle: Math.PI / 3,
    spotPenumbra: 0,
    spotDecay: 0
  }

  const ctrl = gui
  const ambienLightFolder = ctrl.addFolder('ambienLight')
  ambienLightFolder.add(ctrlObj, 'ambienLightintensity', 0, 5)
  ambienLightFolder.addColor(ctrlObj, 'ambienLightColor').onChange(function (clr: string) {
    ambienLight.color = new THREE.Color(clr)
  })

  const spotLightFolder = ctrl.addFolder('spotLight')
  spotLightFolder.add(ctrlObj, 'spotLightintensity', 0, 5)
  spotLightFolder.addColor(ctrlObj, 'spotLightColor').onChange(function (clr: string) {
    spotLight.color = new THREE.Color(clr)
  })

  spotLightFolder.add(ctrlObj, 'spotLightDistance', 0, 1000).onChange(function (dis: number) {
    spotLight.distance = dis
  })

  spotLightFolder.add(ctrlObj, 'spotLightAngle', 0, Math.PI * 2).onChange(function (angle: number) {
    spotLight.angle = angle
  })

  spotLightFolder.add(ctrlObj, 'spotPenumbra', 0, 1).onChange(function (pen: number) {
    spotLight.penumbra = pen
  })

  spotLightFolder.add(ctrlObj, 'spotDecay', 0, 5).onChange(function (dec: number) {
    spotLight.decay = dec
  })

  const geometry = new THREE.BoxGeometry(8, 8, 8)
  const material = new THREE.MeshLambertMaterial({ color: 0xff2288 })
  const cube = new THREE.Mesh(geometry, material)
  cube.castShadow = true
  cube.position.x = 0
  cube.position.y = 8
  cube.position.z = 0
  scene.add(cube)

  render.setAnimationLoop(animation)

  function animation () {
    stats.update()
    lightHelper.update()
    shadowCameraHelper.update()

    ambienLight.intensity = ctrlObj.ambienLightintensity
    spotLight.intensity = ctrlObj.spotLightintensity

    render.render(scene, camera)
  }

  return { camera, render, scene }
}

export {
  createCourse09
}
